package com.huawei.petSystemdemo.utils;

import android.Manifest;
import android.app.Activity;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Looper;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.huawei.hmf.tasks.Task;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.common.ResolvableApiException;
import com.huawei.hms.location.FusedLocationProviderClient;
import com.huawei.hms.location.LocationCallback;
import com.huawei.hms.location.LocationRequest;
import com.huawei.hms.location.LocationResult;
import com.huawei.hms.location.LocationServices;
import com.huawei.hms.location.LocationSettingsRequest;
import com.huawei.hms.location.LocationSettingsResponse;
import com.huawei.hms.location.LocationSettingsStatusCodes;
import com.huawei.hms.location.SettingsClient;

import java.util.List;

public class LocationUtils {
    private final String TAG;
    Activity context;

    // 定位交互接入对象
    private FusedLocationProviderClient fusedLocationProviderClient;
    // 设置
    SettingsClient settingsClient;
    // 定位请求信息对象
    private LocationRequest mLocationRequest;
    // 定位请求回调
    private LocationCallback mLocationCallback;

    public LocationUtils(Activity context, String tag, LocationCallback callback) {
        this.context = context;
        this.TAG = tag;

        settingsClient  = LocationServices.getSettingsClient(context);
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
        mLocationRequest = new LocationRequest();
        // 设置定位类型
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // 设置位置更新的间隔（单位为毫秒）
//        mLocationRequest.setInterval(10000);

        if (callback != null)
            mLocationCallback = callback;
        else
            mLocationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    Log.d(TAG, "回调成功");
                    if (locationResult != null) {
                        // 处理位置回调结果
                        List<Location> locations = locationResult.getLocations();
                        for (Location l : locations) {
                            System.out.println(l);
                        }
                    }
                }
            };
    }

    public void locate() {
        requestPermission();   //请求允许
        checkLocationSettings();    //检查位置设置
        requestLocationUpdates();   //请求位置更新
    }

    private void requestPermission() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
            Log.i(TAG, "android sdk <= 28 Q");
            if (ActivityCompat.checkSelfPermission(context,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(context,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                String[] strings =
                        {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
                ActivityCompat.requestPermissions(context, strings, 1);
            }
        } else {
            // Android SDK>28 所需权限动态申请，需添加“android.permission.ACCESS_BACKGROUND_LOCATION”权限
            if (ActivityCompat.checkSelfPermission(context,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(context,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(context,
                    "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
                String[] strings = {Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        "android.permission.ACCESS_BACKGROUND_LOCATION"};
                ActivityCompat.requestPermissions(context, strings, 2);
            }
        }
    }

    private void checkLocationSettings() {
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();
        // 检查设备定位设置
        settingsClient.checkLocationSettings(locationSettingsRequest)
                // 检查设备定位设置接口成功监听回调
                .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                        System.out.println("定位设置检查成功");
                        // 设置满足定位条件，再发起位置请求
                        requestLocationUpdates();
                    }
                })
                // 检查设备定位设置接口失败监听回调
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                        Log.e(TAG, "定位设置检查失败");
                        // 设置不满足定位条件
                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                try {
                                    ResolvableApiException rae = (ResolvableApiException) e;
                                    // 调用startResolutionForResult可以弹窗提示用户打开相应权限
                                    rae.startResolutionForResult(context, 0);
                                } catch (IntentSender.SendIntentException sie) {
                                    // ...
                                }
                                break;
                        }
                    }
                });
    }

    //请求定位更新
    private void requestLocationUpdates() {
        System.out.println("请求定位更新");
        fusedLocationProviderClient   //定位交互接入对象
                .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        // 接口调用成功的处理
                        System.out.println("定位更新成功");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                        // 接口调用失败的处理
                        System.out.println("定位更新失败");
                    }
                });
    }

    void removeLocationUpdates() {
        // 注意：停止位置更新时，mLocationCallback必须与requestLocationUpdates方法中的LocationCallback参数为同一对象。
        fusedLocationProviderClient.removeLocationUpdates(mLocationCallback)
                // 停止位置更新成功监听回调
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        // ...
                    }
                })
                // 停止位置更新失败监听回调
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                        // ...
                    }
                });
    }

    void getLastLocation() {
        // 获取最后的已知位置
        Task<Location> task = fusedLocationProviderClient.getLastLocation()
                // 获取最后的已知位置成功监听回调
                .addOnSuccessListener(new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location == null) {
                            return;
                        }
                        // 成功时Location对象处理逻辑
                        // ...
                    }
                })
                // 获取最后的已知位置失败监听回调
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(Exception e) {
                        // ...
                    }
                });
    }
}
